﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CrystalCore.Libs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Ivory;
using Jitter;

namespace CrystalCore.Mapping
{
    public abstract class CellBase : ISelectable3D
    {
        protected partial class CellPrim : PhysicsPrim
        {
            public CellPrim(Vector3 pos)
                : base(pos)
            {
                this.IsStatic = true;
                this.AffectedByGravity = false;
                this.Rescale(Vector3.One);
            }

            public Matrix World
            {
                get
                {
                    return
                        Matrix.CreateScale(this.Scale)
                        *
                        Matrix.CreateRotationX(Rotation.X) *
                        Matrix.CreateRotationY(Rotation.Y) *
                        Matrix.CreateRotationZ(Rotation.Z)
                        *
                        Matrix.CreateTranslation(Converter.ConvertVect(this.Position));
                }
            }
        }

        //Fields  
        protected CellPrim CellPrimitive;

        public Element CellElement { get; set; }
        public Vector3 CellOrigin { get { return new Vector3(CellPrimitive.Position.X, 0, CellPrimitive.Position.Z); } }
        public MazePosition MazePosition { get; private set; }

        //cTor
        public CellBase(MazePosition Position)
        {
            this.CellPrimitive = new CellPrim(new Vector3(
                (Position.X * Globals.CellSize.X) + (Globals.CellSize.X / 2),
                -((Globals.CellSize.Y) / 2), 
                (Position.Z * Globals.CellSize.Z) + (Globals.CellSize.Z / 2)));

            MazePosition = Position;     
        }

        //Methods                
        public virtual void DrawCell()
        {
            if (ObjectHolder.GameWorld == null)
                throw new CrystalCoreFrameworkError(CrystalCoreErrors.NoGameWorld);

            if (ObjectHolder.GameWorld == null)
                throw new CrystalCoreFrameworkError(CrystalCoreErrors.NoGameCamera);

            RenderCell();

            if (Globals.DrawPrimitivesInDebugMode)
            {
                if (ObjectHolder.GlobalDebugRenderer == null)
                    throw new CrystalCoreFrameworkError(CrystalCoreErrors.NoGlobalDebugDrawer);


                ObjectHolder.GlobalDebugRenderer.DrawAabb(CellPrimitive.BoundingBox.Min, CellPrimitive.BoundingBox.Max, Globals.DebugColour);
            }
        }
        public abstract void UpdateCell(GameTime time);

        protected abstract void RenderCell();        
        protected abstract void OnCellClicked();
        
        #region ISelectable3D
        public Jitter.Dynamics.RigidBody Body
        {
            get { return this.CellPrimitive; }
        }
        public MazePosition SelectablePosition
        {
            get { return this.MazePosition; }
        }
        private SelectableState _SelectionState;
        public SelectableState SelectionState
        {
            get { return _SelectionState; }
            set
            {
                if (value == SelectableState.Selected)
                    OnCellClicked();

                _SelectionState = value;
            }
        }          
        public string ID
        {
            get;
            set;
        }

        #endregion
    }
}
